package com.ruoyi.service.impl;

import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.entity.*;
import com.ruoyi.mapper.VerUserMapper;
import com.ruoyi.service.VerUserService;
import com.ruoyi.utils.JwtTokenUtils;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

@Service
public class VerUserServiceImpl implements VerUserService {
    @Resource
    private VerUserMapper verUserMapper;

    @Resource
    private JwtTokenUtils jwtTokenUtils;

    /**
     * 更新用户昵称和性别
     *
     * @param userId   用户ID
     * @param nickName 昵称
     * @param gender   性别
     * @return 更新结果
     */
    @Override
    public int updateNickNameAndGender(Long userId, String nickName, String gender) {
        VerUser user = new VerUser();
        user.setUserId(userId);
        user.setNickName(nickName);
        user.setGender(gender);
        return verUserMapper.updateNickNameAndGender(user);
    }

    /**
     * 修改密码
     * @param changePasswordDto 密码修改请求对象
     * @return 是否修改成功
     */
    @Override
    public boolean changePassword(ChangePasswordDto changePasswordDto) {
        // 1. 验证参数
        validateChangePasswordRequest(changePasswordDto);

        // 2. 查询用户信息
        VerUser user = verUserMapper.selectUserById(changePasswordDto.getUserId());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 3. 验证旧密码是否正确
        if (!matchesPassword(changePasswordDto.getOldPassword(), user.getPassword())) {
            throw new RuntimeException("旧密码不正确");
        }

        // 4. 更新密码
        user.setPassword(encodePassword(changePasswordDto.getNewPassword()));
        user.setPwdUpdateDate(new java.util.Date());

        int result = verUserMapper.updatePassword(user);
        return result > 0;
    }

    /**
     * 验证密码修改请求
     * @param dto 请求参数
     */
    private void validateChangePasswordRequest(ChangePasswordDto dto) {
        // 验证新密码和确认密码是否一致
        if (!dto.getNewPassword().equals(dto.getConfirmPassword())) {
            throw new RuntimeException("新密码和确认密码不一致");
        }

        // 验证旧密码和新密码是否一致
        if (dto.getOldPassword().equals(dto.getNewPassword())) {
            throw new RuntimeException("新密码不能与旧密码相同");
        }
    }

    /**
     * 验证密码是否匹配
     * @param rawPassword 原始密码
     * @param encodedPassword 加密后的密码
     * @return 是否匹配
     */
    private boolean matchesPassword(String rawPassword, String encodedPassword) {
        // 使用与登录相同的验证方式
        return SecurityUtils.matchesPassword(rawPassword, encodedPassword);
    }

    /**
     * 加密密码
     * @param password 原始密码
     * @return 加密后的密码
     */
    private String encodePassword(String password) {
        // 使用与注册相同的加密方式
        return SecurityUtils.encryptPassword(password);
    }

    /**
     * 用户注册
     *
     * @param registerDto 注册信息
     */
    @Override
    public void register(RegisterDto registerDto) {
        // 检查邮箱是否已被注册
        VerUser user = verUserMapper.selectUserByEmail(registerDto.getEmail());
        if (StringUtils.isNotNull(user)) {
            throw new ServiceException("邮箱已被注册，请更换其他邮箱");
        }

        VerUser sysUser = new VerUser();
        sysUser.setEmail(registerDto.getEmail());
        sysUser.setNickName(StringUtils.isBlank(registerDto.getNickName()) ?
                "用户_" + System.currentTimeMillis() : registerDto.getNickName());
//        sysUser.setPhonenumber(registerDto.getPhonenumber());
        sysUser.setUserType("user"); // 普通用户
        sysUser.setStatus("0"); // 正常状态
        sysUser.setDelFlag("0"); // 未删除

        // 密码加密
        String encryptPassword = SecurityUtils.encryptPassword(registerDto.getPassword());
        sysUser.setPassword(encryptPassword);

        // 设置时间
        sysUser.setCreateTime(DateUtils.getNowDate());
        sysUser.setPwdUpdateDate(DateUtils.getNowDate());
        sysUser.setCreateBy(sysUser.getNickName());

        // 保存用户
        verUserMapper.insertUser(sysUser);
    }

    /**
     * 用户登录
     *
     * @param loginDto 登录信息
     * @param ipAddr   IP地址
     * @return 登录结果
     */
    @Override
    public LoginVo login(LoginDto loginDto, String ipAddr) {
        // 查询用户
        VerUser user = verUserMapper.selectUserByEmail(loginDto.getEmail());

        // 验证用户是否存在
        if (StringUtils.isNull(user)) {
            throw new ServiceException("邮箱或密码错误");
        }

        // 验证用户状态
        if ("1".equals(user.getStatus())) {
            throw new ServiceException("账号已被停用，请联系管理员");
        }

        // 验证用户是否被删除
        if ("2".equals(user.getDelFlag())) {
            throw new ServiceException("账号已被删除");
        }

        // 验证密码
        if (!SecurityUtils.matchesPassword(loginDto.getPassword(), user.getPassword())) {
            throw new ServiceException("邮箱或密码错误");
        }

        // 更新登录信息
        user.setLoginIp(ipAddr);
        user.setLoginDate(DateUtils.getNowDate());
        user.setUpdateTime(DateUtils.getNowDate());
        verUserMapper.updateById(user);

        //  生成纯JWT Token
        LoginVo loginUser = new LoginVo();
        loginUser.setUserId(user.getUserId());
        loginUser.setNickName(user.getNickName());
//        loginUser.setUser(user);
        String token = jwtTokenUtils.createToken(loginUser);

        // 构建返回结果
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        loginVo.setUserId(user.getUserId());
        loginVo.setNickName(user.getNickName());
        loginVo.setEmail(user.getEmail());

        return loginVo;
    }
}
